<?php

namespace app\common\model;

use think\Db;
use think\Exception;
use think\Model;

class Funds extends Model
{
    // 表名
    protected $name = 'funds';
    
    // 自动写入时间戳字段
    protected $autoWriteTimestamp = true;

    // 追加属性
    protected $append = [
        'create_time_text',
        'update_time_text',
	    'operation_type_text'
    ];
    

    const OPERATION_TYPE_PUSH = 2;
	const OPERATION_TYPE_LESS = 1;
 
	public static $operationTypeList = [
		self::OPERATION_TYPE_PUSH => '收入',
		self::OPERATION_TYPE_LESS => '支出'
	];

	public function getOperationTypeTextAttr($value, $data) {
		$value = $value ? $value : $data['operation_type'];
		$list = self::$operationTypeList;
		return isset($list[$value]) ? $list[$value] : '';
	}


    public function getCreateTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['create_time']) ? $data['create_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }


    public function getUpdateTimeTextAttr($value, $data)
    {
        $value = $value ? $value : (isset($data['update_time']) ? $data['update_time'] : '');
        return is_numeric($value) ? date("Y-m-d H:i:s", $value) : $value;
    }

    protected function setCreateTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }

    protected function setUpdateTimeAttr($value)
    {
        return $value && !is_numeric($value) ? strtotime($value) : $value;
    }
	
    public function user(){
		return $this->belongsTo('user', 'user_id', 'id', '', 'left')
			->setEagerlyType(0);
    }
    
    public function account(){
		return $this->belongsTo('userAccount', 'account_id', 'id', '', 'left')->setEagerlyType(0);
    }
    
    public function type(){
		return $this->belongsTo('fundsType', 'funds_type_id', 'id', '', 'left')->setEagerlyType(0);
    }
	
	/**
	 * 添加流水记录
	 * @param $data
	 * @return bool
	 * @throws \think\exception\PDOException
	 */
    public function addRecord($data){
        $this->startTrans();
        try {
	
	        $accountModel = new UserAccount();
	        $account = $accountModel->find($data['account_id']);
	        //增加减少对应帐号资金
	
	        $amount = $data['amount'];
	        if($data['operation_type'] == self::OPERATION_TYPE_LESS) {
	        	$amount = -$data['amount'];
	        }
	        
	        $data['before_amount'] = $account['balance'];
	        $data['after_amount'] = $account['balance']+$amount;
        	//添加记录
	        $res = $this->allowField(true)
		        ->isUpdate(false)
		        ->save($data);
	        if(!$res) {
	        	throw new Exception('添加资金流水出错');
	        }
	        
	        
	        $accountRes = $accountModel
		        ->where(['id' => $account['id']])
		        ->setInc('balance', $amount);
	        if(!$accountRes) {
	        	throw new Exception('更改帐户资金出错');
	        }
	        
	        $this->commit();
	        return true;
	        
        } catch (Exception $e) {
        	$this->rollback();
        	$this->error = $e->getMessage();
        	return false;
        }
    }
    
    public function editRecord($data) {
    	$row = Db::name('funds')->find($data['id']);
	
	    $this->startTrans();
	    try {
		
		    $accountModel = new UserAccount();
		    
		    //查找新的消费帐号
		    $account = $accountModel->find($data['account_id']);
		    
		    //如果更改了消费帐号
	    	if($row['account_id'] != $data['account_id']) {
	    	    //如果原来是加，那就减金额，是减就加金额
	    	    if($row['operation_type'] == self::OPERATION_TYPE_PUSH) {
	    	    	//原来是加金额，减少帐户资金
	    	        $beforeRes = $accountModel->where(['id' => $row['account_id']])->setDec('balance', $row['amount']);
	    	        if(!$beforeRes) {
	    	        	throw new Exception('减少原来帐号金额出错');
		            }
		            
		            //为这记录之后的数据的更改前金额和更改后金额更改
			        $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
				        ->setDec('before_amount', $row['amount']);
			
			        $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
				        ->setDec('after_amount', $row['amount']);
			        
			        if($beforeDecRes === false || $beforeIncRes === false) {
			        	throw new Exception('更改原帐号资金记录出错');
			        }
		        } else {
	    	    	//原来是减少，添加帐户金额
			        $beforeRes = $accountModel->where(['id' => $row['account_id']])->setInc('balance', $row['amount']);
			        if(!$beforeRes) {
				        throw new Exception('添加原来帐号金额出错');
			        }
			
			        //为这记录之后的数据的更改前金额和更改后金额更改
			        $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
				        ->setInc('after_amount', $row['amount']);
			
			        $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
				        ->setInc('before_amount', $row['amount']);
			
			        if($beforeDecRes === false || $beforeIncRes === false) {
				        throw new Exception('更改原帐号资金记录出错');
			        }
		        }
			
			    //如果现在是加，那就加金额，是减就减金额
			    if($data['operation_type'] == self::OPERATION_TYPE_LESS) {
			    	//现在是减少，减少新帐户金额
				    $beforeRes = $accountModel->where(['id' => $data['account_id']])->setDec('balance', $data['amount']);
				    if(!$beforeRes) {
					    throw new Exception('减少新帐号金额出错');
				    }
				
				    //为这记录之后的数据的更改前金额和更改后金额更改
				    $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
					    ->setDec('before_amount', $data['amount']);
				
				    $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
					    ->setDec('after_amount', $data['amount']);
				
				    if($beforeDecRes === false || $beforeIncRes === false) {
					    throw new Exception('更改新帐号资金记录出错');
				    }
			    } else {
			    	//现在是加，添加新帐户金额
				    $beforeRes = $accountModel->where(['id' => $data['account_id']])->setInc('balance', $data['amount']);
				    if(!$beforeRes) {
					    throw new Exception('添加原来帐号金额出错');
				    }
				
				    //为这记录之后的数据的更改前金额和更改后金额更改
				    $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
					    ->setInc('after_amount', $data['amount']);
				
				    $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
					    ->setInc('before_amount', $data['amount']);
				
				    if($beforeDecRes === false || $beforeIncRes === false) {
					    throw new Exception('更改原帐号资金记录出错');
				    }
			    }
		    } else {
	    		//同一帐户的修改
			    if($data['operation_type'] == $row['operation_type']) {
			    	//相同的操作类型
				    
				    if($data['operation_type'] == self::OPERATION_TYPE_PUSH) {
					    $amount = $data['amount'] > $row['amount'] ? $data['amount'] - $row['amount'] : $row['amount'] - $data['amount'];
				    } else {
					    $amount = $row['amount'] - $data['amount'];
				    }
				    
				    //添加金额
				    //现在是加，添加新帐户金额
				    $beforeRes = $accountModel->where(['id' => $row['account_id']])->setInc('balance', $amount);
				    if(!$beforeRes) {
					    throw new Exception('添加原来帐号金额出错');
				    }
				
				    //为这记录之后的数据的更改前金额和更改后金额更改
				    $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
					    ->setInc('after_amount', $amount);
				
				    $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
					    ->setInc('before_amount', $amount);
				
				    if($beforeDecRes === false || $beforeIncRes === false) {
					    throw new Exception('更改原帐号资金记录出错');
				    }
			    } else {
				    $amount = $data['amount'] + $row['amount'];
			    	//不同类型的操作
				    if($data['operation_type'] == self::OPERATION_TYPE_PUSH) {
					    //现在是加，添加新帐户金额
					    $beforeRes = $accountModel->where(['id' => $row['account_id']])->setInc('balance', $amount);
					    if(!$beforeRes) {
						    throw new Exception('添加原来帐号金额出错');
					    }
					
					    //为这记录之后的数据的更改前金额和更改后金额更改
					    $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
						    ->setInc('after_amount', $amount);
					
					    $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
						    ->setInc('before_amount', $amount);
					
					    if($beforeDecRes === false || $beforeIncRes === false) {
						    throw new Exception('更改原帐号资金记录出错');
					    }
				    } else {
					    //现在是加，添加新帐户金额
					    $beforeRes = $accountModel->where(['id' => $row['account_id']])->setDec('balance', $amount);
					    if(!$beforeRes) {
						    throw new Exception('减少原来帐号金额出错');
					    }
					
					    //为这记录之后的数据的更改前金额和更改后金额更改
					    $beforeIncRes = $this->where(['create_time' => ['gt', $row['create_time']]])
						    ->setDec('after_amount', $amount);
					
					    $beforeDecRes = $this->where(['create_time' => ['gt', $row['create_time']]])
						    ->setDec('before_amount', $amount);
					
					    if($beforeDecRes === false || $beforeIncRes === false) {
						    throw new Exception('更改原帐号资金记录出错');
					    }
				    }
			    }
		    }
		
		    //查找新帐户的上一条资金记录
		    $newAccountRecord = Db::name('funds')
			    ->where(['create_time' => ['lt', $row['create_time']], 'account_id' => $data['account_id']])
			    ->order(['create_time' => 'DESC'])
			    ->find();
	    	if($newAccountRecord) {
			    if($data['operation_type'] == self::OPERATION_TYPE_LESS) {
			    	$beforeAmount = $newAccountRecord['after_amount'];
			    	$afterAmount = $beforeAmount - $data['amount'];
			    } else {
				    $beforeAmount = $newAccountRecord['after_amount'];
				    $afterAmount = $beforeAmount + $data['amount'];
			    }
		    } else {
			    if($data['operation_type'] == self::OPERATION_TYPE_LESS) {
				    $beforeAmount = $account['balance'];
				    $afterAmount = $beforeAmount - $data['amount'];
			    } else {
				    $beforeAmount = $account['balance'];
				    $afterAmount = $beforeAmount + $data['amount'];
			    }
		    }
		
		
		    $data['before_amount'] = $beforeAmount;
		    $data['after_amount'] = $afterAmount;
		    
		    //添加记录
		    $res = $this->allowField(true)
			    ->save($data, ['id' => $data['id']]);
		    if(!$res) {
			    throw new Exception('更改资金流水出错');
		    }
		
		    $this->commit();
		    return true;
		
	    } catch (Exception $e) {
		    $this->rollback();
		    $this->error = $e->getMessage();
		    return false;
	    }
    }
}
